import pymysql
import logging

class DatabaseManager:
    """
    数据库管理类，封装了数据库连接和基本的CRUD操作。
    """

    def __init__(self, host="101.126.16.255", port="3306", user="root", password="wbj19961023", database="wenku", charset='utf8mb4'):
        """
        初始化数据库管理类实例。

        :param host: 数据库服务器地址
        :param port: 数据库服务器端口
        :param user: 数据库用户名
        :param password: 数据库密码
        :param database: 要连接的数据库名
        :param charset: 数据库编码，默认为utf8mb4
        """
        self.host = host
        self.port = port
        self.user = user
        self.password = password
        self.database = database
        self.charset = charset
        self.connection = None  # 数据库连接对象，初始化为None
        self._setup_logger()

    def _setup_logger(self):
        """设置日志记录器。"""
        self.logger = logging.getLogger('DatabaseManager')
        handler = logging.StreamHandler()
        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        handler.setFormatter(formatter)
        self.logger.addHandler(handler)
        self.logger.setLevel(logging.INFO)

    def connect(self):
        """
        连接到数据库。

        使用提供的数据库连接信息创建数据库连接。
        """
        try:
            self.connection = pymysql.connect(host=self.host,
                                              port=self.port,
                                              user=self.user,
                                              password=self.password,
                                              database=self.database,
                                              charset=self.charset,
                                              cursorclass=pymysql.cursors.DictCursor)
            self.logger.info("数据库连接成功")
        except pymysql.MySQLError as e:
            self.logger.error(f"数据库连接失败: {e}")
            raise

    def close(self):
        """
        关闭数据库连接。

        如果当前存在数据库连接，则关闭它。
        """
        if self.connection:
            try:
                self.connection.close()
                self.logger.info("数据库连接已关闭")
            except pymysql.MySQLError as e:
                self.logger.error(f"关闭数据库连接失败: {e}")
                raise

    def execute_query(self, sql, params=None):
        """
        执行查询操作并返回结果。

        :param sql: SQL查询语句
        :param params: SQL语句中的参数，以元组或列表形式提供，默认为None
        :return: 查询结果列表，每个元素是一个字典，代表一行数据
        """
        try:
            with self.connection.cursor() as cursor:
                cursor.execute(sql, params or ())  # 使用或运算确保params不是None时正常传入，否则传入空元组
                self.connection.commit()  # 提交事务，对于查询操作通常不需要，但为了一致性还是提交
                result = cursor.fetchall()  # 返回所有查询结果
                self.logger.info(f"查询执行成功: {sql}")
                return result
        except pymysql.MySQLError as e:
            self.logger.error(f"查询执行失败: {sql}，错误: {e}")
            raise

    def execute_non_query(self, sql, params=None):
        """
        执行非查询操作（如INSERT、UPDATE、DELETE）。

        :param sql: SQL非查询语句
        :param params: SQL语句中的参数，以元组或列表形式提供，默认为None
        :return: 受影响的行数
        """
        try:
            with self.connection.cursor() as cursor:
                cursor.execute(sql, params or ())  # 同上，确保params不是None
                self.connection.commit()  # 提交事务，对于非查询操作是必须的
                affected_rows = cursor.rowcount  # 返回受影响的行数
                self.logger.info(f"非查询执行成功: {sql}")
                return affected_rows
        except pymysql.MySQLError as e:
            self.logger.error(f"非查询执行失败: {sql}，错误: {e}")
            raise

# 使用示例
if __name__ == "__main__":
    db_manager = DatabaseManager('127.0.0.1', 3306, 'your_username', 'your_password', 'your_database')
    db_manager.connect()

    try:
        # 查询
        results = db_manager.execute_query("SELECT * FROM account")
        for row in results:
            print(row)

        # 插入
        insert_sql = "INSERT INTO account (username, password) VALUES (%s, %s)"
        insert_params = ('user2', 'password2')
        db_manager.execute_non_query(insert_sql, insert_params)

        # 更新
        update_sql = "UPDATE account SET password = %s WHERE username = %s"
        update_params = ('newpassword2', 'user2')
        db_manager.execute_non_query(update_sql, update_params)

        # 删除
        delete_sql = "DELETE FROM account WHERE username = %s"
        delete_params = ('user2',)
        db_manager.execute_non_query(delete_sql, delete_params)
    finally:
        db_manager.close()
